import React, { useState, useEffect } from 'react';
import { Grid, Paper, TextField, Button, Box, Select, MenuItem, FormControl, InputLabel, Alert, Typography, Tooltip, Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material';
import LightbulbIcon from '@mui/icons-material/Lightbulb';
import axios from 'axios';

const GAME_STATE_KEY = 'sudoku_game_state';
const BEST_SCORES_KEY = 'sudoku_best_scores';
const API_URL = `${process.env.REACT_APP_API_URL}/api/sudoku`;

const SudokuBoard = () => {
  const [board, setBoard] = useState(Array(9).fill().map(() => Array(9).fill('')));
  const [difficulty, setDifficulty] = useState('medium');
  const [message, setMessage] = useState('');
  const [originalBoard, setOriginalBoard] = useState(null);
  const [time, setTime] = useState(0);
  const [isRunning, setIsRunning] = useState(false);
  const [remainingHints, setRemainingHints] = useState(3);
  const [highlightCell, setHighlightCell] = useState(null);
  const [showRestoreDialog, setShowRestoreDialog] = useState(false);
  const [savedState, setSavedState] = useState(null);
  const [bestScores, setBestScores] = useState({
    easy: Infinity,
    medium: Infinity,
    hard: Infinity
  });
  const [showScoresDialog, setShowScoresDialog] = useState(false);
  const [errors, setErrors] = useState(new Set());

  const formatTime = (seconds) => {
    const minutes = Math.floor(seconds / 60);
    const remainingSeconds = seconds % 60;
    return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
  };

  useEffect(() => {
    let intervalId;
    if (isRunning) {
      intervalId = setInterval(() => {
        setTime((prevTime) => prevTime + 1);
      }, 1000);
    }
    return () => clearInterval(intervalId);
  }, [isRunning]);

  const isValidNumber = (board, row, col, num) => {
    for (let x = 0; x < 9; x++) {
      if (x !== col && board[row][x] === num) return false;
    }
    
    for (let x = 0; x < 9; x++) {
      if (x !== row && board[x][col] === num) return false;
    }
    
    const startRow = Math.floor(row / 3) * 3;
    const startCol = Math.floor(col / 3) * 3;
    for (let i = 0; i < 3; i++) {
      for (let j = 0; j < 3; j++) {
        if (startRow + i !== row && startCol + j !== col && 
            board[startRow + i][startCol + j] === num) {
          return false;
        }
      }
    }
    
    return true;
  };

  const handleCellChange = (row, col, value) => {
    const newValue = value === '' ? '' : parseInt(value, 10);
    if (isNaN(newValue) || newValue < 1 || newValue > 9) return;

    const newBoard = [...board];
    newBoard[row][col] = newValue;
    setBoard(newBoard);

    const newErrors = new Set(errors);
    const cellKey = `${row}-${col}`;

    if (newValue !== '') {
      if (!isValidNumber(newBoard, row, col, newValue)) {
        newErrors.add(cellKey);
      } else {
        newErrors.delete(cellKey);
      }

      for (let i = 0; i < 9; i++) {
        for (let j = 0; j < 9; j++) {
          if (i === row && j === col) continue;
          const otherCellKey = `${i}-${j}`;
          const otherValue = newBoard[i][j];
          
          if (otherValue !== '') {
            if (!isValidNumber(newBoard, i, j, otherValue)) {
              newErrors.add(otherCellKey);
            } else {
              newErrors.delete(otherCellKey);
            }
          }
        }
      }
    } else {
      newErrors.delete(cellKey);
    }

    setErrors(newErrors);

    if (!isRunning) {
      setIsRunning(true);
    }
  };

  const startNewGame = async () => {
    try {
      const response = await axios.get(`${API_URL}/new-game?difficulty=${difficulty}`);
      const newBoard = response.data.board;
      setBoard(newBoard);
      setOriginalBoard(JSON.parse(JSON.stringify(newBoard)));
      setMessage('');
      setTime(0);
      setIsRunning(false);
      setRemainingHints(3);
      setHighlightCell(null);
      setErrors(new Set());
      localStorage.removeItem(GAME_STATE_KEY);
    } catch (error) {
      console.error('Error starting new game:', error);
      setMessage('生成新游戏时出错');
    }
  };

  const validateBoard = async () => {
    try {
      const response = await axios.post(`${API_URL}/validate`, { board });
      if (response.data.valid) {
        setIsRunning(false);
        const isNewBest = updateBestScore();
        setMessage(
          isNewBest 
            ? `恭喜！答案正确！新的最佳记录：${formatTime(time)}` 
            : `恭喜！答案正确！用时：${formatTime(time)}`
        );
      } else {
        setMessage(response.data.message);
      }
    } catch (error) {
      setMessage('验证答案时出错');
    }
  };

  const getHint = async () => {
    if (remainingHints <= 0) {
      setMessage('提示次数已用完');
      return;
    }

    try {
      const response = await axios.post(`${API_URL}/hint`, {
        board,
        remainingHints
      });

      if (response.data.error) {
        setMessage(response.data.message);
        return;
      }

      const { hint } = response.data;
      const newBoard = [...board];
      newBoard[hint.row][hint.col] = hint.value;
      setBoard(newBoard);
      setRemainingHints(response.data.remainingHints);
      
      setHighlightCell({ row: hint.row, col: hint.col });
      setTimeout(() => setHighlightCell(null), 2000);

      if (!isRunning) {
        setIsRunning(true);
      }
    } catch (error) {
      setMessage('获取提示时出错');
    }
  };

  const saveGameState = () => {
    const gameState = {
      board,
      originalBoard,
      difficulty,
      time,
      remainingHints,
      lastSaved: new Date().toISOString()
    };
    localStorage.setItem(GAME_STATE_KEY, JSON.stringify(gameState));
    setMessage('游戏已保存');
  };

  const loadGameState = () => {
    const savedStateStr = localStorage.getItem(GAME_STATE_KEY);
    if (savedStateStr) {
      const state = JSON.parse(savedStateStr);
      setSavedState(state);
      setShowRestoreDialog(true);
    }
  };

  const restoreGame = () => {
    if (savedState) {
      setBoard(savedState.board);
      setOriginalBoard(savedState.originalBoard);
      setDifficulty(savedState.difficulty);
      setTime(savedState.time);
      setRemainingHints(savedState.remainingHints);
      setIsRunning(true);
      setShowRestoreDialog(false);
      setMessage('游戏已恢复');
    }
  };

  const loadBestScores = () => {
    const savedScores = localStorage.getItem(BEST_SCORES_KEY);
    if (savedScores) {
      setBestScores(JSON.parse(savedScores));
    }
  };

  const updateBestScore = () => {
    if (time < bestScores[difficulty]) {
      const newBestScores = {
        ...bestScores,
        [difficulty]: time
      };
      setBestScores(newBestScores);
      localStorage.setItem(BEST_SCORES_KEY, JSON.stringify(newBestScores));
      return true;
    }
    return false;
  };

  useEffect(() => {
    loadBestScores();
    loadGameState();
  }, []);

  useEffect(() => {
    const autoSaveInterval = setInterval(() => {
      if (isRunning) {
        saveGameState();
      }
    }, 60000);

    return () => clearInterval(autoSaveInterval);
  }, [board, originalBoard, difficulty, time, remainingHints, isRunning]);

  const formatBestScore = (score) => {
    return score === Infinity ? '暂无记录' : formatTime(score);
  };

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
      {message && (
        <Alert 
          severity={message.includes('正确') ? 'success' : 'error'} 
          sx={{ 
            mb: 2, 
            width: '100%',
            borderRadius: 2,
            '& .MuiAlert-icon': {
              fontSize: '1.5rem',
            },
          }}
        >
          {message}
        </Alert>
      )}
      
      <Paper 
        elevation={3} 
        sx={{ 
          p: 3, 
          mb: 3, 
          width: '100%',
          background: 'rgba(255, 255, 255, 0.9)',
          backdropFilter: 'blur(10px)',
        }}
      >
        <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 3 }}>
          <FormControl sx={{ minWidth: 120 }}>
            <InputLabel>难度</InputLabel>
            <Select
              value={difficulty}
              label="难度"
              onChange={(e) => setDifficulty(e.target.value)}
              sx={{
                borderRadius: 2,
                '& .MuiOutlinedInput-notchedOutline': {
                  borderColor: 'rgba(0, 0, 0, 0.1)',
                },
              }}
            >
              <MenuItem value="easy">简单</MenuItem>
              <MenuItem value="medium">中等</MenuItem>
              <MenuItem value="hard">困难</MenuItem>
            </Select>
          </FormControl>

          <Box sx={{ display: 'flex', gap: 2, alignItems: 'center' }}>
            <Tooltip title="查看最佳成绩">
              <Button
                variant="outlined"
                color="info"
                onClick={() => setShowScoresDialog(true)}
                size="small"
                sx={{
                  borderRadius: 4,
                  transition: 'all 0.3s',
                  '&:hover': {
                    transform: 'translateY(-2px)',
                    boxShadow: '0 4px 8px rgba(0,0,0,0.1)',
                  },
                }}
              >
                最佳成绩
              </Button>
            </Tooltip>

            <Tooltip title={`剩余提示次数: ${remainingHints}`}>
              <span>
                <Button
                  variant="outlined"
                  color="info"
                  onClick={getHint}
                  disabled={remainingHints <= 0}
                  startIcon={<LightbulbIcon />}
                  sx={{
                    borderRadius: 4,
                    transition: 'all 0.3s',
                    '&:hover': {
                      transform: 'translateY(-2px)',
                      boxShadow: '0 4px 8px rgba(0,0,0,0.1)',
                    },
                  }}
                >
                  提示 ({remainingHints})
                </Button>
              </span>
            </Tooltip>

            <Typography 
              variant="h5" 
              sx={{ 
                fontFamily: 'monospace',
                background: 'linear-gradient(45deg, #2196F3 30%, #21CBF3 90%)',
                color: 'white',
                padding: '8px 16px',
                borderRadius: '8px',
                boxShadow: '0 3px 5px 2px rgba(33, 203, 243, .3)',
                minWidth: '100px',
                textAlign: 'center',
              }}
            >
              {formatTime(time)}
            </Typography>
          </Box>
        </Box>

        <Paper 
          elevation={4} 
          sx={{ 
            p: 2, 
            mb: 3,
            background: 'white',
            borderRadius: 3,
            position: 'relative',
            '&::before': {
              content: '""',
              position: 'absolute',
              top: 0,
              left: 0,
              right: 0,
              bottom: 0,
              borderRadius: 3,
              border: '2px solid rgba(25, 118, 210, 0.3)',
              pointerEvents: 'none',
            }
          }}
        >
          <Grid 
            container 
            spacing={0}
            sx={{
              border: '2px solid rgba(25, 118, 210, 0.5)',
              borderRadius: 1,
              overflow: 'hidden',
              position: 'relative',
              display: 'grid',
              gridTemplateColumns: 'repeat(9, 1fr)',
              gap: 0,
              '& > .MuiGrid-item': {
                padding: 0,
                borderRight: '1px solid rgba(0, 0, 0, 0.1)',
                borderBottom: '1px solid rgba(0, 0, 0, 0.1)',
                '&:nth-of-type(9n)': {
                  borderRight: 'none',
                },
                '&:nth-of-type(n+73)': {
                  borderBottom: 'none',
                },
                '&:nth-of-type(3n)': {
                  borderRight: '2px solid rgba(25, 118, 210, 0.5)',
                },
                '&:nth-of-type(9n)': {
                  borderRight: 'none',
                },
                '&:nth-of-type(n+19):nth-of-type(-n+27), &:nth-of-type(n+46):nth-of-type(-n+54)': {
                  borderBottom: '2px solid rgba(25, 118, 210, 0.5)',
                },
              },
            }}
          >
            {board.map((row, rowIndex) => (
              row.map((cell, colIndex) => {
                const cellKey = `${rowIndex}-${colIndex}`;
                const hasError = errors.has(cellKey);
                const isOriginal = originalBoard && originalBoard[rowIndex][colIndex] !== 0;
                const isHighlighted = highlightCell?.row === rowIndex && highlightCell?.col === colIndex;
                
                return (
                  <Grid 
                    item 
                    key={cellKey}
                    sx={{
                      position: 'relative',
                      width: '100%',
                      aspectRatio: '1',
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                      transition: 'all 0.3s',
                      '&:hover': {
                        backgroundColor: 'rgba(25, 118, 210, 0.04)',
                      },
                      ...(isHighlighted && {
                        '&::before': {
                          content: '""',
                          position: 'absolute',
                          top: 0,
                          left: 0,
                          right: 0,
                          bottom: 0,
                          backgroundColor: 'rgba(255, 243, 205, 0.8)',
                          zIndex: 0,
                        }
                      })
                    }}
                  >
                    <TextField
                      variant="outlined"
                      value={cell || ''}
                      onChange={(e) => handleCellChange(rowIndex, colIndex, e.target.value)}
                      disabled={isOriginal}
                      error={hasError}
                      inputProps={{
                        maxLength: 1,
                        style: { 
                          textAlign: 'center',
                          padding: 0,
                          height: '100%',
                          width: '100%',
                          fontSize: '1.4rem',
                          fontWeight: isOriginal ? 600 : 400,
                          backgroundColor: 'transparent',
                          color: hasError 
                            ? '#d32f2f' 
                            : isOriginal
                            ? '#1976d2' 
                            : '#333333',
                          transition: 'all 0.3s',
                        }
                      }}
                      sx={{
                        width: '100%',
                        height: '100%',
                        '& .MuiOutlinedInput-root': {
                          height: '100%',
                          padding: 0,
                          backgroundColor: isOriginal
                            ? 'rgba(240, 240, 240, 0.8)'
                            : 'transparent',
                          '& fieldset': { 
                            border: 'none',
                          },
                          '&:hover fieldset': { 
                            border: 'none',
                          },
                          '&.Mui-focused fieldset': { 
                            border: 'none',
                          },
                          '&.Mui-focused': {
                            backgroundColor: 'rgba(25, 118, 210, 0.08)',
                          },
                          '& input': {
                            height: '100% !important',
                            padding: '0 !important',
                            display: 'flex',
                            alignItems: 'center',
                            justifyContent: 'center',
                          }
                        },
                      }}
                    />
                  </Grid>
                );
              })
            ))}
          </Grid>
        </Paper>
        
        <Box sx={{ display: 'flex', gap: 2, justifyContent: 'center' }}>
          <Button 
            variant="contained" 
            color="primary" 
            onClick={startNewGame}
            sx={{
              px: 4,
              py: 1.5,
              fontSize: '1.1rem',
              transition: 'all 0.3s',
              '&:hover': {
                transform: 'translateY(-2px)',
                boxShadow: '0 6px 12px rgba(25, 118, 210, 0.3)',
              },
            }}
          >
            开始新游戏
          </Button>
          <Button 
            variant="contained" 
            color="secondary" 
            onClick={validateBoard}
            sx={{
              px: 4,
              py: 1.5,
              fontSize: '1.1rem',
              transition: 'all 0.3s',
              '&:hover': {
                transform: 'translateY(-2px)',
                boxShadow: '0 6px 12px rgba(156, 39, 176, 0.3)',
              },
            }}
          >
            验证答案
          </Button>
          <Button 
            variant="outlined" 
            onClick={saveGameState}
            sx={{
              px: 4,
              py: 1.5,
              fontSize: '1.1rem',
              transition: 'all 0.3s',
              '&:hover': {
                transform: 'translateY(-2px)',
                boxShadow: '0 4px 8px rgba(0,0,0,0.1)',
              },
            }}
          >
            保存游戏
          </Button>
        </Box>
      </Paper>

      <Dialog 
        open={showRestoreDialog} 
        onClose={() => setShowRestoreDialog(false)}
        PaperProps={{
          sx: {
            borderRadius: 3,
            p: 1,
          }
        }}
      >
        <DialogTitle>发现保存的游戏</DialogTitle>
        <DialogContent>
          {savedState && (
            <Typography>
              上次保存时间: {new Date(savedState.lastSaved).toLocaleString()}
              <br />
              难度: {savedState.difficulty === 'easy' ? '简单' : 
                     savedState.difficulty === 'medium' ? '中等' : '困难'}
              <br />
              用时: {formatTime(savedState.time)}
            </Typography>
          )}
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setShowRestoreDialog(false)}>开始新游戏</Button>
          <Button onClick={restoreGame} variant="contained">
            继续上次游戏
          </Button>
        </DialogActions>
      </Dialog>

      <Dialog 
        open={showScoresDialog} 
        onClose={() => setShowScoresDialog(false)}
        PaperProps={{
          sx: {
            borderRadius: 3,
            p: 1,
          }
        }}
      >
        <DialogTitle>最佳成绩</DialogTitle>
        <DialogContent>
          <Box sx={{ minWidth: 200, pt: 1 }}>
            <Typography variant="body1" gutterBottom>
              简单难度：{formatBestScore(bestScores.easy)}
            </Typography>
            <Typography variant="body1" gutterBottom>
              中等难度：{formatBestScore(bestScores.medium)}
            </Typography>
            <Typography variant="body1" gutterBottom>
              困难难度：{formatBestScore(bestScores.hard)}
            </Typography>
            {bestScores[difficulty] !== Infinity && (
              <Typography 
                variant="body2" 
                color="primary" 
                sx={{ mt: 2, fontStyle: 'italic' }}
              >
                当前难度最佳记录：{formatTime(bestScores[difficulty])}
              </Typography>
            )}
          </Box>
        </DialogContent>
        <DialogActions>
          <Button 
            variant="outlined" 
            color="error" 
            onClick={() => {
              setBestScores({
                easy: Infinity,
                medium: Infinity,
                hard: Infinity
              });
              localStorage.removeItem(BEST_SCORES_KEY);
              setShowScoresDialog(false);
            }}
          >
            重置记录
          </Button>
          <Button onClick={() => setShowScoresDialog(false)}>
            关闭
          </Button>
        </DialogActions>
      </Dialog>
    </Box>
  );
};

export default SudokuBoard; 